/*
 * Unidata Platform Community Edition
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 * This file is part of the Unidata Platform Community Edition software.
 *
 * Unidata Platform Community Edition is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Unidata Platform Community Edition is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

package org.unidata.mdm.search.configuration;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.unidata.mdm.search.util.SearchUtils;

/**
 * @author Mikhail Mikhailov
 * Root spring context link.
 */
@Configuration
public class SearchConfiguration {
    /**
     * Logger for this class.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchConfiguration.class);
    /**
     * Search client bean.
     * @param searchCluster cluster string
     * @param searchNodes search nodes string
     * @return client or null
     */
    @Bean
    public Client client(
            @Value("${" + SearchConfigurationConstants.PROPERTY_CLUSTER_NAME + "}") final String searchCluster,
            @Value("${" + SearchConfigurationConstants.PROPERTY_CLUSTER_NODES + "}") final String searchNodes) {

        if (StringUtils.isBlank(searchCluster)) {
            LOGGER.error("Cannot create search client instance. Search cluster name is blank.");
            return null;
        }

        List<TransportAddress> addresses = new ArrayList<>();
        if (!StringUtils.isBlank(searchNodes)) {

            String[] tokens = searchNodes.trim().split(SearchUtils.COMMA_SEPARATOR);
            for (String token : tokens) {
                String[] pair = token.split(SearchUtils.COLON_SEPARATOR);
                String host = pair.length > 0 ? pair[0] : null;
                String port = pair.length > 1 ? pair[1] : SearchConfigurationConstants.DEFAULT_PORT_VALUE;
                try {
                    addresses.add(new TransportAddress(InetAddress.getByName(host), Integer.valueOf(port)));
                } catch (UnknownHostException e) {
                    LOGGER.error("UHE caught!", e);
                }
            }
        }

        if (addresses.isEmpty()) {
            LOGGER.error("Cannot create search client instance. Nodes are invalid or absent.");
            return null;
        }

        Settings.Builder b = Settings.builder()
                .put(SearchUtils.ES_CLUSTER_NAME_SETTING, searchCluster.trim());

        TransportClient searchClient = new PreBuiltTransportClient(b.build());
        for (TransportAddress address : addresses) {
            searchClient.addTransportAddress(address);
        }

        return searchClient;
    }
}
